home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Carousel
/
CAROUSEL.cdr
/
mactosh
/
code
/
p_serlib.sit
/
Serial Library Source Code
/
serial.readFileTilStr.dll.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-07-27
|
13KB
|
457 lines
/***********************************************************************/
/*
/* serial.readFileTilStr.dll.c
/* by Atul Butte
/* Copyright ⌐ 1989 by Microsoft Corporation
/* All Rights Reserved
/*
/* version 1.0
/*
/*
/* This CALL/REGISTER will read from the serial port until the specifed
/* string is read up to 255 characters. The characters are stored in
/* a file.
/*
/* Excel usage:
/*
/* = Register( "serial library", "serial.readTilStr", "IHDJCD" )
/* = Call( ref, portNumber, matchStr, maxTime, readConfigStr, fileName )
/*
/* where
/* portNumber = number of port (1 = modem, 2 = printer)
/* matchStr = keep reading until we read this string
/* maxTime = maximum amount of time to wait for characters
/* in 1/60 second units
/* readConfigStr = configuration of communications protocol, etc
/* fileName = name of file in which to store characters
/*
/***********************************************************************/
/***********************************************************************/
/*
/* D E F I N E S
/*
/***********************************************************************/
#define ROUTINE_NAME "serial.readFileTilStr"
#define hNIL 0L
#define pNIL 0L
#define kcchBuff 64
/***********************************************************************/
/*
/* I N C L U D E S
/*
/***********************************************************************/
#include "serial.h"
#include "error.h"
#include "get_port.h"
#include "interpret.h"
#include "get_read_flags.h"
/***********************************************************************/
/*
/* P R O T O T Y P E S
/*
/***********************************************************************/
void initialize_next( Ptr pnxt, char *pstMatch );
char check_for_match( char cRead, unsigned char cCurrentChar, unsigned char cMatchLength, char *pstMatch, Ptr pnxt );
short open_file( char *stFilename );
void close_file( short refnum, char *pch, unsigned short dch );
Boolean store_character( short refnum, char cRead, char *pch, unsigned short *dch );
/***********************************************************************/
/*
/* main
/*
/***********************************************************************/
pascal short main( port, pstMatch, timeDur, pszConfig, pstFilename )
unsigned short port; /* serial port to use */
char *pstMatch; /* keep reading until we read this string */
unsigned long timeDur; /* maximum time to wait for chars (in ticks) */
char *pszConfig; /* communications configuration string */
register char *pstFilename; /* name of file in which to save characters */
{
register OSErr err; /* result code from Toolbox routines */
ParamBlockRec param; /* parameter block for read/write */
Boolean fEcho = false; /* flag for echoing characters */
Boolean fEdit = false; /* flag for allowing edit characters */
Boolean fStripLF = false; /* flag for stripping line feeds */
Boolean fStrip8Bit = false; /* flag for stripping high bit */
Boolean fAddLF = false; /* flag for adding LF after CR */
Boolean fIgnore = false; /* flag for ignoring escape chars */
Handle hnxt; /* handle to the next table */
register Ptr pnxt; /* pointer to the next table */
long cchBuff = 0; /* number of characters waiting in read buffer */
register unsigned long timeStop; /* time at which to stop */
short refIn; /* reference number for input port */
short refOut; /* reference number for output port */
char chRead; /* buffer used to read a character */
register char ch; /* character read */
char echoBackspace[3]; /* characters to send to echo Backspace */
char echoLinefeed; /* characters to send to echo Linefeed */
register unsigned char cchMatched; /* number of characters matching so far */
register unsigned char cchMatch; /* number of characters to match */
char *pch; /* buffer used in file reading */
unsigned short ichBuff = 0; /* index in buffer */
short refFile; /* reference number for file */
RememberA0();
SetUpA4();
if( pstFilename == pNIL ) {
display_error( "The fifth parameter must be a file name." );
RestoreA4( );
return( errParam );
}
if( *pstFilename == 0 ) {
display_error( "The fifth parameter must be a file name." );
RestoreA4( );
return( errParam );
}
if( pszConfig == pNIL ) {
display_error( "The fourth parameter must be a configuration string." );
RestoreA4( );
return( errParam );
}
if( pstMatch == pNIL ) {
display_error( "The second parameter must be a string to match." );
RestoreA4( );
return( errParam );
}
if( *pstMatch == 0 ) {
display_error( "You must specify a string to match with at least one character." );
RestoreA4( );
return( errParam );
}
err = get_port( port, &refIn, &refOut );
if( err != noErr ) {
display_error( "Illegal port number." );
RestoreA4( );
return( err );
}
pch = NewPtr( kcchBuff );
if( pch == pNIL ) {
display_error( "Not enough memory to allocate buffer." );
RestoreA4( );
return( errMemory );
}
ichBuff = 0;
if( ( refFile = open_file( pstFilename ) ) == 0 ) {
RestoreA4( );
return( errDiskWrite );
}
get_read_flags( pszConfig, &fEcho, &fEdit, &fStripLF, &fStrip8Bit, &fAddLF, &fIgnore );
if( !fIgnore ) {
err = interpret( pstMatch );
if( err != noErr ) {
RestoreA4( );
return( errStrFormat );
}
}
cchMatched = 1;
cchMatch = *pstMatch;
if( cchMatch > 1 ) {
hnxt = NewHandle( (long) *pstMatch + 1 );
HLock( hnxt );
pnxt = *hnxt;
initialize_next( pnxt, pstMatch );
}
if( fEcho ) {
echoBackspace[0] = kchBackspace;
echoBackspace[1] = ' ';
echoBackspace[2] = kchBackspace;
if( fAddLF ) {
echoLinefeed = kchLinefeed;
}
}
timeStop = TickCount( ) + timeDur;
while( true ) {
if( ( timeDur != 0 ) && ( TickCount( ) >= timeStop ) ) {
break;
}
err = SerGetBuf( refIn, &cchBuff );
if( err != noErr ) {
display_error( "Error trying to count buffer." );
err = errSerialGetBuf;
goto CleanExit;
}
if( cchBuff == 0 )
continue;
param.ioParam.ioReqCount = 1;
param.ioParam.ioBuffer = &chRead;
param.ioParam.ioRefNum = refIn;
err = PBRead( ¶m, false );
if( err != noErr ) {
display_error( "Error reading from serial port." );
err = errSerialRead;
goto CleanExit;
}
ch = chRead;
if( ( (ch == kchBackspace) || (ch == kchDelete) ) && (fEdit) ) {
if( fEcho ) {
param.ioParam.ioReqCount = 3;
param.ioParam.ioRefNum = refOut;
param.ioParam.ioBuffer = echoBackspace;
err = PBWrite( ¶m, false );
if( err != noErr ) {
display_error( "Error echoing backspace to serial port." );
err = errSerialWrite;
goto CleanExit;
}
}
} else if( fEcho ) {
param.ioParam.ioReqCount = 1;
param.ioParam.ioRefNum = refOut;
param.ioParam.ioBuffer = &chRead;
err = PBWrite( ¶m, false );
if( err != noErr ) {
display_error( "Error echoing to serial port." );
err = errSerialWrite;
goto CleanExit;
}
if( (ch == kchReturn) && (fAddLF) ) {
param.ioParam.ioReqCount = 1;
param.ioParam.ioRefNum = refOut;
param.ioParam.ioBuffer = &echoLinefeed;
err = PBWrite( ¶m, false );
if( err != noErr ) {
display_error( "Error echoing linefeed to serial port." );
err = errSerialWrite;
goto CleanExit;
}
}
}
if( fStrip8Bit ) {
ch &= 0x7F;
}
if( (ch == kchLinefeed) && (fStripLF) ) {
} else {
if( !store_character( refFile, ch, pch, &ichBuff ) ) {
err = errDiskWrite;
goto CleanExit;
}
cchMatched = check_for_match( ch, cchMatched, cchMatch, pstMatch, pnxt );
if( cchMatched > cchMatch ) /* if we found a match */
break;
}
}
if( cchMatched > cchMatch ) {
err = noErr;
} else {
err = errTimeOut;
}
CleanExit:
close_file( refFile, pch, ichBuff );
if( cchMatch > 1 )
DisposHandle( hnxt );
RestoreA4();
return( err );
}
/***********************************************************************/
/*
/* initialize_next
/*
/***********************************************************************/
void initialize_next( pnxt, pstMatch )
register Ptr pnxt; /* pointer to the next table */
char *pstMatch; /* keep reading until we read this string */
{
register unsigned long i = 1, j = 0; /* index through match string */
register unsigned char cchMatch = *pstMatch; /* number of characters to match */
pnxt[1] = 0;
do {
if( ( j == 0 ) || ( pstMatch[i] == pstMatch[j] ) ) {
i++;
j++;
pnxt[i] = j;
} else {
j = pnxt[j];
}
} while( i <= cchMatch );
}
/***********************************************************************/
/*
/* check_for_match
/*
/***********************************************************************/
char check_for_match( ch, cchMatched, cchMatch, pstMatch, pnxt )
register char ch; /* character read */
register unsigned char cchMatched; /* number of characters matching so far */
register unsigned char cchMatch; /* number of characters to match */
char *pstMatch; /* keep reading until we read this string */
register Ptr pnxt; /* pointer to the next table */
{
if( cchMatch == 1 ) {
if( ch == pstMatch[1] ) {
return( 2 );
} else {
return( 1 );
}
} else {
do {
if( ( cchMatched == 0 ) || ( ch == pstMatch[cchMatched] ) ) {
cchMatched++;
break;
} else {
cchMatched = pnxt[cchMatched];
}
} while( cchMatched <= cchMatch );
return( cchMatched );
}
}
/***********************************************************************/
/*
/* open_file
/*
/***********************************************************************/
short open_file( pstFilename )
register char *pstFilename; /* name of file in which to save characters */
{
short refFile; /* reference number for file */
register OSErr err; /* result code from Toolbox routines */
err = FSOpen( pstFilename, 0, &refFile );
if( err == fnfErr ) {
err = Create( pstFilename, 0, 'XCEL', 'TEXT' );
if( err != noErr ) {
display_error( "Error creating file." );
return( 0 );
}
err = FSOpen( pstFilename, 0, &refFile );
if( err != noErr ) {
display_error( "Error opening file." );
return( 0 );
}
} else if( err == noErr ) {
err = SetEOF( refFile, 0L );
if( err != noErr ) {
display_error( "Error deleting existing file." );
return( 0 );
}
} else {
display_error( "Error opening file." );
return( 0 );
}
return( refFile );
}
/***********************************************************************/
/*
/* close_file
/*
/***********************************************************************/
void close_file( refFile, pch, ichBuff )
short refFile; /* reference number for file */
char *pch; /* buffer used in file reading */
unsigned short ichBuff; /* index in buffer */
{
register OSErr err; /* result code from Toolbox routines */
long cch; /* number of character left in buffer */
if( ichBuff > 0 ) {
cch = ichBuff;
err = FSWrite( refFile, &cch, pch );
if( err == dskFulErr ) {
display_error( "Disk full error." );
} else if( err == vLckdErr ) {
display_error( "The volume is locked." );
} else if( err != noErr ) {
display_error( "Error in writing to file." );
}
}
err = FSClose( refFile );
if( err != noErr ) {
display_error( "Error closing file." );
}
DisposPtr( pch );
}
/***********************************************************************/
/*
/* store_character
/*
/***********************************************************************/
Boolean store_character( refFile, ch, pch, pichBuff )
short refFile; /* reference number for file */
register char ch; /* character read */
char *pch; /* buffer used in file reading */
unsigned short *pichBuff; /* index in buffer */
{
register OSErr err; /* result code from Toolbox routines */
long cch; /* number of character left in buffer */
if( *pichBuff < kcchBuff ) {
pch[*pichBuff] = ch;
( *pichBuff )++;
} else {
cch = kcchBuff;
err = FSWrite( refFile, &cch, pch );
if( err == dskFulErr ) {
display_error( "Disk full error." );
return( false );
} else if( err == vLckdErr ) {
display_error( "The volume is locked." );
return( false );
} else if( err != noErr ) {
display_error( "Error in writing to file." );
return( false );
}
*pichBuff = 1;
*pch = ch;
}
return( true );
}
#include "get_port.c"
#include "interpret.c"
#include "get_read_flags.c"